import { BaseService, CoolCommException } from "@cool-midway/core";
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Equal, Repository } from "typeorm";
import { ProviderInfoEntity } from "../entity/info";
import { CapacityEntity } from "../../transport/entity/capacity";
import { Config, Inject, Provide } from "@midwayjs/core";
import { BaseSysLoginService } from "../../base/service/sys/login";
import { ProviderSmsService } from "./sms";
import * as jwt from 'jsonwebtoken';
import { ProviderTeamEntity } from "../entity/team";
import { Utils } from "../../../comm/utils";
import { TransportType } from "../../transport/entity/type";


@Provide()
export class ProviderLoginService extends BaseService {
    @InjectEntityModel(ProviderInfoEntity)
    providerInfoEntity: Repository<ProviderInfoEntity>;

    @Config('module.provider.jwt')
    jwtConfig: {
        expire: number;
        refreshExpire: number;
        secret: string;
    };

    @Inject()
    baseSysLoginService: BaseSysLoginService;

    @Inject()
    providerSmsService: ProviderSmsService;

    @Inject()
    utils: Utils;


    /**
     * 发送手机验证码
     * @param phone
     * @param captchaId
     * @param code
     */
    async smsCode(phone: string, captchaId: string, code: string) {
        // 1、检查图片验证码  2、发送短信验证码
        const check = await this.baseSysLoginService.captchaCheck(captchaId, code);
        if (!check) {
            throw new CoolCommException('图片验证码错误');
        }
        await this.providerSmsService.sendSms(phone);
    }

    /**
       * 手机登录
       * @param phone
       * @returns
       */
    async phone(phone: string) {
        const provider = await this.providerInfoEntity.manager.transaction(async manager => {
            // 查询是否已存在
            let exist = await manager.findOne(ProviderInfoEntity, { where: { phone: Equal(phone) } });
            if (!exist) {
                exist = await manager.save(ProviderInfoEntity, { phone });
            }
            return exist;
        });
        // 仅使用 id 生成 token，内部会再次查询以补充必要信息
        return this.token({ id: provider.id } as any);
    }

    /**
     *  手机验证码登录
     * @param phone
     * @param smsCode
     */
    async phoneVerifyCode(phone: string, smsCode: string) {
        // 1、检查短信验证码  2、登录
        const check = await this.providerSmsService.checkCode(phone, smsCode);
        if (check) {
            return await this.phone(phone);
        } else {
            throw new CoolCommException('验证码错误');
        }
    }

    /**
     * 获得token
     * @param info
     * @returns
     */
    async token(info: ProviderInfoEntity) {
        const { expire, refreshExpire } = this.jwtConfig;
        return {
            expire,
            token: await this.generateToken(info),
            refreshExpire,
            refreshToken: await this.generateToken(info, true),
        };
    }

    /**
     * 生成token
     * @param tokenInfo 信息
     * @param roleIds 角色集合
     */
    async generateToken(info: ProviderInfoEntity, isRefresh = false) {
        const { expire, refreshExpire, secret } = this.jwtConfig;
        const provider = await this.providerInfoEntity.findOneBy({ id: Equal(info.id) });
        const tokenInfo = {
            isRefresh,
            ...info,
            tenantId: provider?.tenantId,
        };
        return jwt.sign(tokenInfo, secret, {
            expiresIn: isRefresh ? refreshExpire : expire,
        });
    }

    /**
  * 刷新token
  * @param refreshToken
  */
    async refreshToken(refreshToken) {
        try {
            const info = jwt.verify(refreshToken, this.jwtConfig.secret);
            if (!info['isRefresh']) {
                throw new CoolCommException('token类型非refreshToken');
            }
            const providerInfo = await this.providerInfoEntity.findOneBy({
                id: info['id'],
            });
            return this.token(providerInfo);
        } catch (e) {
            throw new CoolCommException(
                '刷新token失败，请检查refreshToken是否正确或过期'
            );
        }
    }

}